home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / db / esm-3.1 / esm-3 / usr / local / sm / src / serverlib / log / openLogDisk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-05  |  6.2 KB  |  239 lines

  1. /*
  2.  *   $RCSfile: openLogDisk.c,v $  
  3.  *   $Revision: 1.1.1.1 $  
  4.  *   $Date: 1996/05/04 21:55:50 $      
  5.  */ 
  6. /**********************************************************************
  7. * EXODUS Database Toolkit Software
  8. * Copyright (c) 1991 Computer Sciences Department, University of
  9. *                    Wisconsin -- Madison
  10. * All Rights Reserved.
  11. *
  12. * Permission to use, copy, modify and distribute this software and its
  13. * documentation is hereby granted, provided that both the copyright
  14. * notice and this permission notice appear in all copies of the
  15. * software, derivative works or modified versions, and any portions
  16. * thereof, and that both notices appear in supporting documentation.
  17. *
  18. * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
  19. * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.  
  20. * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
  21. * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  22. *
  23. * The EXODUS Project Group requests users of this software to return 
  24. * any improvements or extensions that they make to:
  25. *
  26. *   EXODUS Project Group 
  27. *     c/o David J. DeWitt and Michael J. Carey
  28. *   Computer Sciences Department
  29. *   University of Wisconsin -- Madison
  30. *   Madison, WI 53706
  31. *
  32. *     or exodus@cs.wisc.edu
  33. *
  34. * In addition, the EXODUS Project Group requests that users grant the 
  35. * Computer Sciences Department rights to redistribute these changes.
  36. **********************************************************************/
  37.  
  38. #include "sysdefs.h"
  39. #include "ess.h"
  40. #include "checking.h"
  41. #include "trace.h"
  42. #include "error.h"
  43. #include "list.h"
  44. #include "pool.h"
  45. #include "tid.h"
  46. #include "io.h"
  47. #include "lock.h"
  48. #include "object.h"
  49. #include "msgdefs.h"
  50. #include "thread.h"
  51. #include "semaphore.h"
  52. #include "latch.h"
  53. #include "link.h"
  54. #include "lsn.h"
  55. #include "bf.h"
  56. #include "log.h"
  57. #include "volume.h"
  58. #include "openlog.h"
  59. #include "disk.h"
  60. #include "trans.h"
  61. #include "logrecs.h"
  62. #include "log_intfuncs.h"
  63. #include "log_extfuncs.h"
  64. #include "bf_extfuncs.h"
  65. #include "io_extfuncs.h"
  66. #include "disk_funcs.h"
  67. #include "recover_extfuncs.h"
  68. #include "thread_globals.h"
  69. #include "log_globals.h"
  70. #include "io_globals.h"
  71.  
  72.  
  73. extern int    errno;
  74. extern FILE*    sm_ErrorStream;
  75.  
  76. /* set in server/ options handling */
  77. VOLID        LogVolid;
  78.  
  79.  
  80.  void
  81. openLogDisk ()
  82.  
  83. {
  84.     VOLREC                *volRec;
  85.     BOOL                performRecovery;    
  86.     int                    minLogSpace;
  87.  
  88.     TRACE(TR_LOG, TR_LEVEL_1);
  89.  
  90.     /*
  91.      *    initialize the log link
  92.      */
  93.     LogLink.id = 1000;
  94.     LogLink.flags = LINK_FREE;
  95.     LogLink.linkClass = CL_DISK;
  96.     initializeListElement( &(LogLink.list), (char *) &LogLink );
  97.     initializeList( &(LogLink.tcbList) );
  98.     initializeList( &(LogLink.volList) );
  99.     initializeList( &(LogLink.transList) );
  100.  
  101.  
  102.     /*
  103.      *     Set up space for holding list of mounted volumes to
  104.      *    add to the checkpoint record
  105.      */
  106.     CheckpointVolumes = (VOLIDNAME*) malloc(NumVolumes * sizeof(*CheckpointVolumes));
  107.     if (CheckpointVolumes == NULL) {
  108.         SM_ERROR(TYPE_STOP, esmMALLOCFAILED);
  109.     }
  110.  
  111.     /*
  112.      *    No checkpoint has had its dirty page table flushed yet
  113.      */
  114.     LastFlushedCheckpoint.offset = NULL_LSN;
  115.     LastFlushedCheckpoint.wrapCount = 0;
  116.     OldestDirtyPageLSN = LastFlushedCheckpoint;
  117.     
  118.     /*
  119.      *    mount the volume: first we need to get the volume id from
  120.      *  the file.
  121.      */
  122.     if ((volRec = io_MountLogVolume(LogVolid)) == NULL)    {
  123.  
  124.         fprintf(sm_ErrorStream, "SERVER ERROR: Cannot mount the log volume: %d\n", LogVolid);
  125.         SM_ERROR(TYPE_STOP, Active->errno);
  126.         return;
  127.     }
  128. #ifdef DEBUG
  129.     if (!(volRec->volflags & VOL_RAWDEV)) {
  130.         fprintf(sm_ErrorStream, "NOTE: log volume is not a raw disk, so fsyncs will be performed\n");
  131.     }
  132. #endif
  133.  
  134.     /*
  135.      *    link the new disk to the log link
  136.      */
  137.     linkVolume( &LogLink, volRec );
  138.  
  139.     /*
  140.      *    check to see if there is a log on this disk
  141.      */
  142.     if (volRec->header->logFileAddr != NULLPID)    {
  143.         int readPages;
  144.         int writePages;
  145.  
  146.         /* Decide if we will recover the log or regenerate it */
  147.         performRecovery = RecoverLog && volRec->header->dismountEndOfLog.wrapCount != NULL_LOG_WRAP_COUNT;
  148.  
  149.         /*
  150.          *    Open the log file.
  151.          *    The log write buffer group should have enough pages
  152.          *    to support writing pages in MAX_IO_LIST chunks.
  153.          *    The log read buffer needs only a small amount since pages
  154.          *    are rarely re-read and we have no prefetching.
  155.          */
  156.         writePages = (MAX_IO_LIST+MAX_IO_LIST/2)*RAISETWO(volRec->header->logFileBlock2size - MIN_PAGE2SIZE);
  157.         readPages = (MAX_IO_LIST/2)*RAISETWO(volRec->header->logFileBlock2size - MIN_PAGE2SIZE);
  158.  
  159.         if (openLogFile(volRec, writePages, readPages, performRecovery))    {
  160.  
  161.             /*
  162.              *    signal any waiters
  163.              */
  164.             notify( &(volRec->tcbList), esmFAILURE, Active->errno);
  165.  
  166.             /*
  167.              *    return indication that mount failed 
  168.              */
  169.             SM_ERROR(TYPE_STOP, esmINTERNAL);
  170.             return;
  171.         }
  172.  
  173.         /*
  174.          *  Make sure the log is large enough
  175.          */
  176.         minLogSpace = 2 * MAX_LOGREC_LEN + /* 2 checkpoints */ 
  177.                       2 * MAX_LOGREC_LEN + /* 1 record and undo */
  178.                       LOG_SLACK;
  179.         if (OpenLog.fileBytes < minLogSpace) {
  180.             fprintf(sm_ErrorStream, "SERVER ERROR: log volume is too small\n");
  181.             fprintf(sm_ErrorStream, "\tMake sure it is formatted with at least %d log pages\n", minLogSpace/OpenLog.pageSize + 1);
  182.             SM_ERROR(TYPE_STOP, esmLOGTOOSMALL);
  183.         }
  184.  
  185.         /* see if the log needs to be regenerated */
  186.         if (performRecovery) {
  187.  
  188.             /*
  189.              *    recover the log file
  190.              */
  191.             recoverLog();
  192.  
  193.         } else {
  194.  
  195.             if (volRec->header->dismountEndOfLog.wrapCount == NULL_LOG_WRAP_COUNT)    {
  196.                 fprintf(sm_ErrorStream, "SERVER: log volume is new -- automatically regenerating the log\n");
  197.             }
  198.             
  199.             CheckpointsEnabled = FALSE;  // do not allow checkpoints
  200.  
  201.             /*
  202.              *    regenerate the log
  203.              */
  204.             if (regenLog( &OpenLog )) {
  205.  
  206.                 /*
  207.                  *    signal any waiters
  208.                  */
  209.                 notify( &(volRec->tcbList), esmFAILURE, Active->errno);
  210.  
  211.                 /*
  212.                  *    return indication that mount failed 
  213.                  */
  214.                 SM_ERROR(TYPE_STOP, esmINTERNAL);
  215.                 return;
  216.             }
  217.  
  218.             CheckpointsEnabled = TRUE;  // allow checkpoints
  219.         }
  220.  
  221.         /* record current end of log for use by clients */
  222.         OpenLog.nextValidLSN.wrapCount  = OpenLog.wrapCount;
  223.         OpenLog.nextValidLSN.offset = 
  224.             FIRST_LSN_ON_PAGE(OpenLog.tailLSN, (&OpenLog));
  225.                 
  226.  
  227.     } else {
  228.         
  229.         /*
  230.          *    Invalid logging volume
  231.          */
  232.         fprintf(sm_ErrorStream, "SERVER ERROR: volume %d is not a log volume.\n", LogVolid);
  233.         SM_ERROR(TYPE_STOP, esmBADLOGVOLUME);
  234.         return;
  235.     }
  236.  
  237.     return;
  238. }
  239.